package com.zwh.sharding.config.sharding.strategy;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.NumberFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

/**
 * 实现精确算法,按照自然月进行分片
 * @author zwh
 * @date 2023-5-12
 */
public class DatePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Date> {


    private static final Logger logger = LoggerFactory.getLogger(DatePreciseShardingAlgorithm.class);

    /**
     *  将日期时间格式化成yyyyMM，然后与名表名称列表进行后缀匹配
     * @param availableTargetNames 分片的数据源dataSource列表 或者 table列表
     * @param preciseShardingValue 分片的条件字段值, shardingColumn: create_time，比如创建时间字段的值
     * @return 返回分片条件匹配到的 某个数据源，或者某个表名称
     */
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> preciseShardingValue) {
        Date date = preciseShardingValue.getValue();
        logger.info("Sharding input:" + preciseShardingValue.getValue());
        String suffix = getSuffixByYearMonth(date);
        for (String targetName : availableTargetNames) {
            logger.info("suffix:" + suffix + ", targetName:{}" + targetName);
            if (targetName.endsWith(suffix)) {
                return targetName;
            }
        }
        throw new IllegalArgumentException("未找到匹配的目标名称");

    }
    /**
     * 自然月为个位数的，进行补零，如07 、08 、09
     * 生成日期的格式：yyyyMM, 比如202305,202311
     **/
    private static String getSuffixByYearMonth(Date date) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMinimumIntegerDigits(2);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR)  +"" +  nf.format((calendar.get(Calendar.MONTH) + 1));
    }
}
